local RUtil = {}

--- 根据路径读取技能
---@param package Package
RUtil.loadSkillSkelsByPackage = function(package)
  local path = "./packages/aaa_Romantic/pkg/"..package.name.."/skills"
  local skels = {}
  local normalized_dir = path
      :gsub("^%.+/", "")
      :gsub("/+$", "")
      :gsub("/", ".")
  for _, filename in ipairs(FileIO.ls(path)) do
    -- 别加载下划线开头的模板技能哈
    if filename:sub(-4) == ".lua" and filename ~= "init.lua" and not filename:startsWith("_") then
      local skel = Pcall(require, normalized_dir .. "." .. filename:sub(1, -5))
      if skel then
        -- 如果返回了一个skel表
        if type(skel) == "table" and not skel.class then
          for _, v in ipairs(skel) do
            table.insert(skels, v)
          end
        else
          table.insert(skels, skel)
        end
      end
    end
  end
  package:loadSkillSkels(skels)
end

--- 加减谋略值
---@param room Room @ 房间
---@param player ServerPlayer @ 角色
---@param num integer @ 加减值，负为减
RUtil.handleMoulue = function(room, player, num)
  local n = player:getMark("@rmt_moulue") or 0
  local new_n = math.min(math.max(n + num, 0), 5)
  room:setPlayerMark(player, "@rmt_moulue", new_n)
  room:sendLog{
    type = num > 0 and "#addMoulue" or "#minusMoulue",
    from = player.id,
    arg = math.abs(num),
    arg2 = new_n,
  }
  room:handleAddLoseSkills(player, player:getMark("@rmt_moulue") > 0 and "rmt__miaoji" or "-rmt__miaoji", nil, false, true)
end

Fk:loadTranslationTable{
  ["@rmt_moulue"] = "谋略值",
  ["#addMoulue"] = "%from 加了 %arg 点谋略值，现在的谋略值为 %arg2 点",
  ["#minusMoulue"] = "%from 减了 %arg 点谋略值，现在的谋略值为 %arg2 点",
}

--- 令一个技能视为未发动/重置技能
---@param player ServerPlayer
---@param skill string|Skill
---@param clear? boolean @ 是否重置技能（清除标记）
RUtil.resetSkill = function (player, skill, clear)
  if type(skill) == "string" then
    skill = Fk.skills[skill]
  end
  local skel = skill:getSkeleton()
  if skel then
    player:setSkillUseHistory(skel.name, 0, Player.HistoryPhase)
    player:setSkillUseHistory(skel.name, 0, Player.HistoryTurn)
    player:setSkillUseHistory(skel.name, 0, Player.HistoryRound)
    player:setSkillUseHistory(skel.name, 0, Player.HistoryGame)
    if clear then
      skel:onLose(player, false)
      skel:onAcquire(player, false)
    end
  end
  player.room:sendLog{type = "#RUtilResetSkill", from = player.id, arg = skill.name}
end

Fk:loadTranslationTable{
  ["#RUtilResetSkill"] = "%from 的技能 %arg 已重置",
}

--- 通过事件数据查找事件
---@generic T: GameEvent
---@param data TriggerData @ 事件数据
---@param eventType? T @ 事件类型，不填则查找所有
---@return T?
RUtil.findGameEventByData = function(data, eventType)
  local room = RoomInstance
  if not room then return nil end
  local logic = room.logic
  local events = logic.all_game_events
  if eventType then
    eventType = logic.event_recorder[eventType] or Util.DummyTable
  end
  for i = #events, 1, -1 do
    local e = events[i]
    if e.data == data then
      return e
    end
  end
  return nil
end


--- 判断此伤害是否为闪电伤害
---@param data DamageData
RUtil.isLightningDamage = function(data)
  if data.skillName then
    if data.skillName == "lightning_skill" or Fk:translate(data.skillName, "zh_CN") == "闪电" then
      return true
    end
  end
  if data.from then
    if Fk:translate(data.from.general, "zh_CN") == "闪电" or Fk:translate(data.from.deputyGeneral, "zh_CN") == "闪电" then
      return true
    end
  end
  -- 非常愚蠢的假闪电判定，令我检索困难
  local room = data.to.room---@type Room
  local currentEvent = RUtil.findGameEventByData(data, GameEvent.Damage)
  if not currentEvent then return false end
  -- 寻找进行闪电判定的父事件，如闪电卡牌，或者角色技能造成的模拟闪电判定
  local skillEvent = currentEvent:findParent(GameEvent.SkillEffect)
  if not skillEvent then return false end
  local id = currentEvent.id - 1
  -- 由于闪电的判定和伤害事件不属于父子关系，而是兄弟关系，故如此检索
  local lastEvent
  while id > skillEvent.id do
    local e = room.logic.all_game_events[id]
    if not e then break end
    if e.parent == skillEvent then
      lastEvent = e
      break
    end
    id = id - 1
  end
  -- 查找本伤害事件上一个兄弟是否为闪电判定
  if lastEvent and lastEvent.event == GameEvent.Judge then
    local judgeData = lastEvent.data---@type JudgeData
    -- 严谨，防止修改闪电技能名
    if judgeData.reason and string.find(judgeData.reason, "lightning") then
      return true
    end
  end
  return false
end


return RUtil
